package com.ddz.library.EventBus

import android.util.Log
import com.ddz.library.log.JKLog

object EventBus {
    val normalEntityMethods = hashMapOf<String, ArrayList<MethodEntity>>()

    fun register(any: Any) {
        val methods = any.javaClass.declaredMethods
        methods.forEach { method ->
            val annotations = method.annotations
            annotations.forEach { annotation ->
                val annotationInfo = annotation.annotationClass
                if (annotationInfo.javaObjectType == EventFun::class.java) {
                    val realAnnotation = method.getAnnotation(EventFun::class.java)
                    var entity = normalEntityMethods[realAnnotation.tag]
                    if (entity == null) {
                        entity = arrayListOf()
                    }
                    val methodEntity = MethodEntity(method.name, if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) method.parameterCount else method.parameterTypes.size, any)
                    entity.add(methodEntity)
                    normalEntityMethods[realAnnotation.tag] = entity
                }
            }
        }
    }

    fun unregister(any: Any) {
        val currentMethods = any.javaClass.declaredMethods
        currentMethods.forEach { method ->
            val annotations = method.annotations
            annotations.forEach { annotation ->
                val annotationInfo = annotation.annotationClass
                if (annotationInfo.javaObjectType == EventFun::class.java) {
                    val realAnnotation = method.getAnnotation(EventFun::class.java)
                    val methods = normalEntityMethods[realAnnotation.tag]
                    if (methods != null && methods.size == 1) {
                        normalEntityMethods.remove(realAnnotation.tag)
                    } else if (methods != null) {
                        val iterator = methods.iterator()
                        while (iterator.hasNext()) {
                            val methodEntity = iterator.next()
                            if (methodEntity.any == any) {
                                iterator.remove()
                            }
                        }
                    }
                }
            }
        }
    }

    fun execute(tag: String, vararg entity: Any) {
        var isSuccessExecute = false
        val methods = normalEntityMethods[tag]
        if (methods != null && methods.size > 0) {
            methods.forEach { methodEntity ->
                if (entity.isNotEmpty() && entity.size == methodEntity.parameterCount) {
                    isSuccessExecute = true
                    val classArray = entity.map { it::class.java }.toTypedArray()
                    val method = methodEntity.any.javaClass.getMethod(methodEntity.methodName, *classArray)
                    method.invoke(methodEntity.any, *entity)
                } else if (entity.isEmpty() && entity.size == methodEntity.parameterCount) {
                    isSuccessExecute = true
                    val method = methodEntity.any.javaClass.getMethod(methodEntity.methodName)
                    method.invoke(methodEntity.any)
                }
            }
        } else {
            JKLog.w("EntityBus","您没有注册接收实体的对象${entity.javaClass.simpleName}，请在接收实体对象的类中调用at com.dd_z.library.EntityBus.EntityBus.register(EntityBus.kt:9)")
        }
        if (!isSuccessExecute) {
            JKLog.w("EntityBus","传递的参数个数没有找到对应的方法")
        }
    }
}